home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / program / 598 / source / screen.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-03-17  |  7.1 KB  |  349 lines

  1. #include <signal.h>
  2. #include <stdlib.h>
  3. #include <ioctl.h>
  4. #include <ctype.h>
  5. #include <basepage.h>
  6. #include <string.h>
  7. #include <osbind.h>
  8. #include <xbra.h>
  9. #include <sysvars.h>
  10. #include <linea.h>
  11. #include <macros.h>
  12.  
  13. #ifdef bool
  14. #undef bool
  15. #endif
  16.  
  17. typedef short    bool;
  18.  
  19. BASEPAGE    *master = (BASEPAGE *) 0;
  20. char    *master_var;
  21.  
  22. #define kByte    * 1024L
  23.  
  24. extern long    _stksize = 2 kByte;
  25. extern char    *_ltoa();
  26. extern long    modul(const char *);
  27. extern long    set_x(const char *);
  28. extern long    set_y(const char *);
  29. extern long    log_x(const char *);
  30. extern long    log_y(const char *);
  31.  
  32. typedef struct {
  33.     char    *master_name;
  34.     short    function_type;
  35.     long    (*function_entry)(const char *cmdline);
  36. } func;
  37.  
  38. func    module_entries[] = {
  39.     { "SCREEN", 0, modul }
  40. };
  41.  
  42. #define _MODUL_MAGIC    0x5343524EL    /* 'SCRN' */
  43. #define _MMX_MAGIC    0x4D4D5845L    /* 'MMXE' */
  44.  
  45. struct head {
  46.     char        *module_description;
  47.     short        module_version;
  48.     short        number_of_functions;
  49.     func        *jump_table;
  50.     long        module_magic;    /* 'SCRN' */
  51.     long        xbra_magic;    /* 'XBRA' */
  52.     long        mmx_magic;    /* 'MMXE' */
  53.     struct head    *next;
  54.     short        jump;
  55.     long        (*this)();
  56. } module_header = {
  57.     "    Master-Module-eXtension for screen setting\r\n"
  58.     "\n"
  59.     "        Usage        |    Explanation\r\n"
  60.     "    ------------------------+--------------------------\r\n"
  61.     "    screen            | show screen parameters\r\n"
  62.     "    screen help        | print this help message\r\n"
  63.     "    screen min_x <num>    | set minimal screen column\r\n"
  64.     "    screen min_y <num>    | set minimal screen line\r\n"
  65.     "    screen max_x <num>    | set maximal screen column\r\n"
  66.     "    screen max_y <num>    | set maximal screen line\r\n",
  67.     1,
  68.     1,
  69.     module_entries,
  70.     _MODUL_MAGIC,
  71.     _XBRA_MAGIC,
  72.     _MMX_MAGIC,
  73.     (struct head *) 0,
  74.     _JMP_OPCODE,
  75.     (long (*)()) 0
  76. };
  77.  
  78. #define WRITE(f,text)    write(f, text, strlen(text))
  79.  
  80. static short    initial_max_x;
  81. static short    initial_max_y;
  82. static bool    is_color;
  83. static short    screen_x_offset = 0;
  84. static short    screen_y_offset = 0;
  85. static short    font_x_offset;
  86. static short    font_y_offset;
  87.  
  88. long
  89. set_x(const char *cmd)
  90. {
  91.     short    x;
  92.     short    old_x;
  93.  
  94.     old_x = V_CEL_MX;
  95.     if(!*cmd) {
  96.         return(old_x);
  97.     } else {
  98.         x = atoi(cmd);
  99.         x = min(initial_max_x - screen_x_offset,x);
  100.         x = max(0,x);
  101.         V_CEL_MX = x;
  102.         return(0);
  103.     }
  104. }
  105.  
  106. long
  107. set_y(const char *cmd)
  108. {
  109.     short    y;
  110.     short    old_y;
  111.  
  112.     old_y = V_CEL_MY;
  113.     if(!*cmd) {
  114.         return(old_y);
  115.     } else {
  116.         y = atoi(cmd);
  117.         y = min(initial_max_y - screen_y_offset,y);
  118.         y = min(initial_max_y - (screen_x_offset != 0),y);
  119.         y = max(0,y);
  120.         V_CEL_MY = y;
  121.         return(0);
  122.     }
  123. }
  124.  
  125. long
  126. log_x(const char *cmd)
  127. {
  128.     short    x;
  129.     short    old_x;
  130.  
  131.     old_x = screen_x_offset;
  132.     if(!*cmd) {
  133.         return(old_x);
  134.     } else {
  135.         is_color = (VPLANES > 1);
  136.         x = atoi(cmd);
  137.         if(is_color && (x & 1)) WRITE(2,"Sorry only even values allowed on color screens\r\n");
  138.         x = (x + is_color) & ~is_color;
  139.         x = min(x,initial_max_x & ~is_color);
  140.         x = max(x,0);
  141.         screen_x_offset = x;
  142.         old_x = min(V_CEL_MX + old_x,initial_max_x) - x;
  143.         V_CEL_MX = max(old_x,0);
  144.         V_CEL_MY = min(V_CEL_MY,initial_max_y - (screen_x_offset != 0));
  145.         write(2, "\33H", 2);
  146.         Setscreen(Physbase()+screen_y_offset*VWRAP*font_y_offset+screen_x_offset*font_x_offset,-1,-1);
  147.         Vsync();
  148.         return(0);
  149.     }
  150. }
  151.  
  152. long
  153. log_y(const char *cmd)
  154. {
  155.     short    y;
  156.     short    old_y;
  157.  
  158.     old_y = screen_y_offset;
  159.     if(!*cmd) {
  160.         return(old_y);
  161.     } else {
  162.         y = atoi(cmd);
  163.         y = min(y,initial_max_y);
  164.         y = max(y,0);
  165.         V_CEL_MY = min(V_CEL_MY + old_y,initial_max_y - (screen_x_offset != 0)) - y;
  166.         screen_y_offset = y;
  167.         write(2, "\33H", 2);
  168.         Setscreen(Physbase()+screen_y_offset*VWRAP*font_y_offset+screen_x_offset*font_x_offset,-1,-1);
  169.         Vsync();
  170.         return(0);
  171.     }
  172. }
  173.  
  174. long
  175. modul(const char *cmdlin)
  176. {
  177.     char    output[30];
  178.  
  179.     if(!*cmdlin) {
  180.         _ltoa(log_x(""), output, 10);
  181.         WRITE(1,output);
  182.         write(1, " ", 1);
  183.         _ltoa(log_y(""), output, 10);
  184.         WRITE(1,output);
  185.         write(1, " ", 1);
  186.         _ltoa(set_x(""), output, 10);
  187.         WRITE(1,output);
  188.         write(1, " ", 1);
  189.         _ltoa(set_y(""), output, 10);
  190.         WRITE(1,output);
  191.         write(1, "\r\n", 2);
  192.         return(0);
  193.     } else if(!strcmp(cmdlin,"help")) {
  194.         WRITE(1,module_header.module_description);
  195.     } else if(cmdlin[5] && cmdlin[5] != ' ') {
  196.         return(1);
  197.     } else if(!strncmp(cmdlin,"min_x",5)) {
  198.         log_x(cmdlin+5);
  199.     } else if(!strncmp(cmdlin,"min_y",5)) {
  200.         log_y(cmdlin+5);
  201.     } else if(!strncmp(cmdlin,"max_x",5)) {
  202.         set_x(cmdlin+5);
  203.     } else if(!strncmp(cmdlin,"max_y",5)) {
  204.         set_y(cmdlin+5);
  205.     }
  206.     strcpy(output,"setenv LINES ");
  207.     _ltoa(V_CEL_MY+1, output+13, 10);
  208.     WRITE(2,output);
  209.     system(output);
  210.     return(0);
  211. }
  212.  
  213. struct head    *current;
  214.  
  215. static long    my_cookies[16] = {
  216.     _MODUL_MAGIC, (long) &module_header,
  217.     0L, 8L
  218. };
  219.  
  220. void
  221. remove_cookies()
  222. {
  223.     set_sysvar_to_long(_p_cookies,0L);
  224. }
  225.  
  226. void
  227. remove_cookie()
  228. {
  229.     long    *cp;
  230.  
  231.     if(cp = (long *) get_sysvar(_p_cookies)) {
  232.         while(*cp && *cp != _MODUL_MAGIC) cp += 2;
  233.         while(*cp) {
  234.             cp[0] = cp[2];
  235.             cp[1] = cp[3];
  236.             cp += 2;
  237.         }
  238.     }
  239. }
  240.  
  241. void
  242. install_cookie(int resident)
  243. {
  244.     long    *cp;
  245.     long    cookies_used = 0;
  246.     long    tmp;
  247.  
  248.     initial_max_x = V_CEL_MX;
  249.     initial_max_y = V_CEL_MY;
  250.     font_x_offset = VWRAP / (initial_max_x + 1);
  251.     font_y_offset = (V_Y_MAX + 1) / (initial_max_y + 1);
  252.     if(!(cp = (long *) get_sysvar(_p_cookies))) {
  253.         if(!resident) {
  254.             write(2, "Unable to install cookie!\r\n", 27);
  255.             exit(1);
  256.         }
  257.         signal(SIGRESET,remove_cookies);
  258.         set_sysvar_to_long(_p_cookies,(long)(cp = my_cookies));
  259.     }
  260.     while(*cp && *cp != _MODUL_MAGIC) {
  261.         cp += 2;
  262.         cookies_used++;
  263.     }
  264.     if(*cp) {
  265.         current = (struct head *) cp[1];
  266.         return;
  267.     }
  268.     if(!(cp[1] - cookies_used - 1)) {
  269.         write(2, "No room for cookie!\r\n", 21);
  270.         exit(1);
  271.     }
  272.     *cp++ = _MODUL_MAGIC;
  273.     tmp = *cp;
  274.     *cp++ = (long) (current = &module_header);
  275.     *cp++ = 0L;
  276.     *cp = tmp;
  277.     return;
  278. }
  279.  
  280. void
  281. install_module(int resident, char *firstcmd)
  282. {
  283.     long    keep;
  284.  
  285.     install_cookie(resident);
  286.     if(master) {
  287.         strcpy(master_var, "Master-Module ");
  288.         _ltoa(current, master_var+14, 10);
  289.     }
  290.     if(current != &module_header) {
  291.         (*(current->jump_table[0].function_entry))(firstcmd);
  292.         exit(0);
  293.     }
  294.     if(!*firstcmd) modul("help");
  295.     else modul(firstcmd);
  296.     if(!resident) return;
  297.     keep = _base->p_tlen + _base->p_dlen + _base->p_blen
  298.         + sizeof(BASEPAGE);
  299.     _base = _base->p_parent;
  300.     Ptermres(keep, 0);
  301. }
  302.  
  303. void
  304. remove_module()
  305. {
  306.     remove_cookie();
  307. }
  308.  
  309. void
  310. usage(char *prog)
  311. {
  312.     write(2, "Usage: [ module ] ", 18);
  313.     WRITE(2, prog);
  314.     write(2, " [ <cmd> ]\r\n", 12);
  315.     exit(2);
  316. }
  317.  
  318. main(int argc, char *argv[])
  319. {
  320.     char    *mmx;
  321.     BASEPAGE    *caller;
  322.     char    *prog;
  323.     char    *firstcmd;
  324.  
  325.     if(**argv) prog = *argv;
  326.     else prog = "screen";
  327.     argc--;
  328.     argv++;
  329.     if(argc) {
  330.         firstcmd = *argv;
  331.         argc--;
  332.         argv++;
  333.     } else firstcmd = "";
  334.     if(argc) usage(prog);
  335.     if(mmx = getenv("MMX")) {
  336.         if(strncmp(mmx, "Master-Call", 11)) exit(1);
  337.         mmx += 11;
  338.         if(!(master = (BASEPAGE *) strtol(mmx, &mmx, 10)) ||
  339.            !(master_var = (char *) strtol(mmx, &mmx, 10)) ||
  340.            !(caller = (BASEPAGE *) strtol(mmx, &mmx, 10)) ||
  341.            (caller != _base->p_parent))
  342.             exit(1);
  343.         install_module(1, firstcmd);
  344.     } else if(!system(NULL)) install_module(1, firstcmd);
  345.     install_module(0, firstcmd);
  346.     system("-i");
  347.     remove_module();
  348. }
  349.